package com.cedifie.lendapp.http

import com.cedifie.http.OkHttp
import com.cedifie.http.cache.CacheEntity
import com.cedifie.http.cache.CacheMode
import com.cedifie.http.callback.StringCallback
import com.cedifie.http.cookie.CookieJarImpl
import com.cedifie.http.cookie.store.DBCookieStore
import com.cedifie.http.interceptor.HttpLoggingInterceptor
import com.cedifie.http.model.HttpHeaders
import com.cedifie.http.model.Response
import com.cedifie.lendapp.BuildConfig
import com.cedifie.lendapp.MyApplication
import com.cedifie.lendapp.config.CedConfigs
import com.cedifie.lendapp.http.ApiService.addCommonParams
import com.cedifie.lendapp.utils.event.CedEventManager
import com.lib.base.utils.log.JsonFormat
import com.lib.base.utils.log.LogHelper
import okhttp3.OkHttpClient
import org.json.JSONObject
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.logging.Level

/**
 * Cedifie
 * @Author wwdeng
 * @CreateTime: 2024/6/12 17:38
 * @Annotation：网络请求
 */
class OkHttpLoader: IHttpLoader {

    init {
        OkHttp.getInstance().init(MyApplication.app)
        val builder = OkHttpClient.Builder()
        //log相关
        val loggingInterceptor = HttpLoggingInterceptor(CedConfigs.CED_APPNAME)
        if (BuildConfig.isDebug){
            loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY) //log打印级别，决定了log显示的详细程度
        } else {
            loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.NONE) //log打印级别，决定了log显示的详细程度
        }
        loggingInterceptor.setColorLevel(Level.INFO) //log颜色级别，决定了log在控制台显示的颜色
        builder.addInterceptor(loggingInterceptor) //添加OkGo默认debug日志
        //第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确

        //超时时间设置，默认60秒
        builder.readTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的读取超时时间
        builder.writeTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的写入超时时间
        builder.connectTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的连接超时时间
        //自动管理cookie（或者叫session的保持），以下几种任选其一就行
        //builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效
        builder.cookieJar(CookieJarImpl(DBCookieStore(MyApplication.context))) //使用数据库保持cookie，如果cookie不过期，则一直有效

        // 其他统一的配置
        // 详细说明看GitHub文档：https://github.com/jeasonlzy/
        OkHttp.getInstance().init(MyApplication.app) //必须调用初始化
            .setOkHttpClient(builder.build()) //建议设置OkHttpClient，不设置会使用默认的
            .setCacheMode(CacheMode.NO_CACHE) //全局统一缓存模式，默认不使用缓存，可以不传
            .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE) //全局统一缓存时间，默认永不过期，可以不传
            .setRetryCount(3) //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0

        //添加通用请求头
        val httpHeaders = HttpHeaders()
        httpHeaders.put("appid", CedConfigs.CED_APPNAME)
        httpHeaders.put("product", CedConfigs.CED_APPNAME)
        OkHttp.getInstance().addCommonHeaders(httpHeaders)
    }

    /**
     * post 请求
     */
    override fun postCedAction(url: String, params: JSONObject, callback: IHttpCallback) {
        params.addCommonParams()
        val aesParams = AESCryptUtil.encryptDefault(params.toString())
        LogHelper.e("HttpUrl：  $url")
        LogHelper.e("HttpParams： $params")
        LogHelper.e("HttpParams AES：  $aesParams")

        OkHttp.post<String>(url) // 请求方式和请求url
            .tag(this) // 请求的 tag, 主要用于取消对应的请求
            .upString(aesParams)
            .execute(object : StringCallback() {
                override fun onSuccess(response: Response<String>) {
                    val body = response.body()
                    if (response.code() != 200 || body == null || body.isEmpty()){
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",response.code())
                        errorObj.put("errorMsg",response.message())
                        callback.onRequestError(errorObj)
                        return
                    }

                    val result = AESCryptUtil.decryptDefault(body)
                    if (result.isNotEmpty()){
                        Thread { LogHelper.i(JsonFormat.format(result)) }.start()
                        val data = JSONObject(result)
                        callback.onRequestSuccess(data)
                    } else {
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",-1)
                        errorObj.put("errorMsg","http request error $result")
                        callback.onRequestError(errorObj)
                    }
                }

                override fun onError(response: Response<String>) {
                    val errorObj = JSONObject()
                    errorObj.put("errorCode",response.code())
                    errorObj.put("errorMsg",response.message())
                    callback.onRequestError(errorObj)
                }
                override fun onFinish() {
                    callback.onRequestFinish()
                }
            })
    }

    /**
     * 添加打点事件
     */
    override fun addCedEventAction(eventName: String, remark: String) {
        val eventType = eventName.uppercase()//转大写
        CedEventManager.getInstance().insertCedEvent(eventType,remark)
//        val httpUrl = ApiService.getHttpUrl(ApiService.API_URL.CED_API_COMMON_URL)
//        val params = JSONObject().addCommonParams().apply {
//            put("path", ApiService.API_PATH.CED_API_TRACK_EVENT_PATH)
//            put("type",eventType)//事件类型
//            put("remark",remark)//事件备注
//        }
//        val aesParams = AESCryptUtil.encryptDefault(params.toString())
//        LogHelper.e("event url：  $httpUrl")
//        LogHelper.e("event params： $params")
//        LogHelper.e("event params AES：  $aesParams")
//        OkHttp.post<String>(httpUrl) // 请求方式和请求url
//            .tag(this) // 请求的 tag, 主要用于取消对应的请求
//            .upString(aesParams)
//            .execute(object : StringCallback() {
//                override fun onSuccess(response: Response<String>) {
//                }
//                override fun onError(response: Response<String>) {
//                }
//                override fun onFinish() {
//                }
//            })
    }

    /**
     * 文件上传
     */
    override fun uploadCedFileAction(httpUrl: String, filePath: String, callback: StringCallback) {
        if (filePath.isEmpty()){
            return
        }
        OkHttp.post<String>(httpUrl) // 请求方式和请求url
            .tag(this) // 请求的 tag, 主要用于取消对应的请求
            .params("image",File(filePath))   //这种方式为一个key，对应一个文件
            .isMultipart(true)
            .execute(callback)
    }
}